﻿using System;

namespace 面向对象.泛型
{
    class Program
    {
        static void Main(string[] args)
        {
            // ctrl + k+c  :注释语句
            // ctrl+k+u  ：解除注释语句
            var miantiao = new Person<Person4>(new Person4("耀耀",10,"面团",3));
            miantiao.huo();
            miantiao.qie(); // 按下 alt 键 在用鼠标左键撸串,然后就可以统一改东西
            miantiao.zhu();
        }
    }
    // T :泛型参数，约定在 Person 逻辑中使用的 材料。
    // 泛型约束：语法为 [where T：xxx]
    // xxx = 具体的 类类型、结构、接口 ：Person、Book、IEatable
    // xxx = 抽象的 类类型、结构、接口：class 、struct 、(不能用interface 关键字)
    // xxx  =  new() ,代表 泛型T有一个无参构造函数可以调用,只有声明了 new() 才能够 使用 new T();
    //public class Person<T> where T : struct //测试了抽象的结构的约束
    //public class Person<T> where T : class
    //public class Person<T> where T : interface // 接口关键字不能作为约束
    //public class Person<T> where T : ISoft // 约束可以为具体的接口
    // 有了约束，可以访问约束中的类型的成员
    // 可以理解为占位
    #region 约束类类型
    //public class Person<T>where T : class约束泛型方法为引用类型
    //{

    //}
    //public class Person1<T>where T : struct 约束泛型方法为值类型或结构类型
    //{

    //}
    // public class Person2<T>where T :interface接口关键字不可以进行约束但是可以约束具体接口
    //{

    //}
    //public class Person3<T>where T : Person2//约束具体接口
    // {

    // }
    //public class person4<T>where T : new()//表示泛型T有一个无参数的构造函数可以调用
    //{

    //}
    #endregion

    public class Person<T>where T : Person2
    {
        private T target;//使用泛型类必须进行初始化对象
        public Person(T target)
        {
            this.target = target;//target：目标

        }
        public void huo()
        {
            Console.WriteLine($"{target.age}岁的{target}在和{target.time}个月保质期的{target.type}");
        }
        public void qie()
        {
            Console.WriteLine($"{target.age}岁的{typeof(T).Name}在切{target.time}个月保质期的{target.type}");
        }
        public void zhu()
        {
            Console.WriteLine($"{target.age}岁的{target.name}在煮{target.time}个月保质期的{target.type}");
        }
        //typeof(T)获取当前类型的类名、
        //GetType().Name//获取所在地址的类名。GetType()获取所在地址

    }

    public class Person4 : Person2//将接口中的成员全部实现
    {
        public string name { get; set; }
        public int age { get; set; }
        public string type { get; set; }//材质
        public int time { get; set; }//有效期
        public Person4(string name,int age,string type,int time)
        {
            this.name = name;
            this.age = age;
            this.type = type;
            this.time = time;
        }
        public override string ToString()
        {
            return "猪八戒";
        }
    }
    public interface Person2
    {
        public string name { get; set; }//名字
        public int age { get; set; }//年龄
        /// <summary>
        /// 材质
        /// </summary>
        string type { get; set; }
        /// <summary>
        /// 有效期
        /// <br>过了有效期会失去弹性</br>
        /// </summary>
        int time { get; set; }
    }
}
